﻿/*
 * (c) Stefan Bojarovski 2010
 * */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASTBuilder
{
    class BooleanExpressionNode : NodesCollection, IArithmeticNode
    {
        private LexemeType lexType = LexemeType.BOOL_EXPRESSION;
        private TokenType boolExpressionType;
        private ITreeNode firstOperand;
        private ITreeNode secondOperand;

        public BooleanExpressionNode(TokenType someTType, ITreeNode fOperand, ITreeNode sOperand)
        {
            boolExpressionType = someTType;
            firstOperand = fOperand;
            secondOperand = sOperand;
        }
        public LexemeType getLexemeType()
        {
            return lexType;
        }
        public void setNegative() { }
        public void printNode(String parentLevel, StreamWriter someStream)
        {
            someStream.WriteLine(parentLevel + " " + "BoolExpression: ");
            someStream.WriteLine(parentLevel + " " + "First Operand: ");
            firstOperand.printNode(parentLevel + " ", someStream);
            if (boolExpressionType != TokenType.UNKNOWN)
            {
                someStream.WriteLine(parentLevel + " " + boolExpressionType.ToString());
            }
            if (secondOperand != null)
            {
                someStream.WriteLine(parentLevel + " " + "Second Operand: ");
                secondOperand.printNode(parentLevel + " ", someStream);
            }
        }
        public List<Command> evalNode(ref Direction next, 
                                        ref Dictionary<String, Pair<IdentifierType, object>> Environment)
        {
            Command first = firstOperand.evalNode(ref next, ref Environment)[0];
            Command second;
            Command result;

            if (secondOperand != null)
            {
                second = secondOperand.evalNode(ref next,ref Environment)[0];
                object Value = null;

                switch (boolExpressionType)
                {
                    case TokenType.EQUALS:
                        Value = object.Equals(first.getIdValue(), second.getIdValue());
                        break;
                    case TokenType.GREATER:
                        Value = ((int)first.getIdValue() > (int)second.getIdValue());
                        break;
                    case TokenType.GREATEREQ:
                        Value = ((int)first.getIdValue() >= (int)second.getIdValue());
                        break;
                    case TokenType.LESS:
                        Value = ((int)first.getIdValue() < (int)second.getIdValue());
                        break;
                    case TokenType.LESSEQ:
                        Value = ((int)first.getIdValue() <= (int)second.getIdValue());
                        break;
                    case TokenType.NOTEQUAL:
                        Value = !object.Equals(first.getIdValue(), second.getIdValue());
                        break;
                    /*case TokenType.FUNBIND:
                        Value = new Pair<IArithmeticNode, IArithmeticNode>((IArithmeticNode)firstOperand, (IArithmeticNode)secondOperand);
                        break;*/
                }
                result = new Command(CommandType.EVALUABLE, null, Value);
            }
            else
            {
                result = new Command(CommandType.EVALUABLE, first.getIdName(), first.getIdValue());
            }
            List<Command> boolExprResult = new List<Command>();
            boolExprResult.Add(result);
            return boolExprResult;
        }
    }
}
